﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace YunLib.DAL
{
    internal class DataMapping<TModel> where TModel : class
    {
        //#region 数据库类型+DataBaseType
        ///// <summary> 
        ///// 数据库类型 
        ///// </summary> 
        //public static string DataBaseType
        //{
        //    get
        //    {
        //        string strType = ConfigurationManager.AppSettings["DataBaseType"];
        //        if (!string.IsNullOrEmpty(strType))
        //        {
        //            return strType;
        //        }
        //        else
        //        {
        //            return string.Empty;
        //        }
        //    }
        //}
        //#endregion

        #region 主键属性字段+PrimaryKey
        /// <summary> 
        /// 主键字段名称 
        /// </summary> 
        public static string PrimaryKey
        {
            get
            {
                Type t = typeof(TModel);
                TableInfoAttribute tableInfo = t.GetCustomAttribute(typeof(TableInfoAttribute), true) as TableInfoAttribute;
                if (tableInfo != null)//如果没有标识表信息特性，则通过表名向数据库中得到主键信息 
                {
                    return tableInfo.PrimaryKey;
                }
                else
                {
                    string tableName = TableName();
                    return DB.ExecuteScalar<string>("SELECT name FROM SysColumns WHERE id=Object_Id('" + tableName + "') and colid=(select top 1 colid from sysindexkeys where id=Object_Id('" + tableName + "'))");
                }
            }
        }
        #endregion

        #region 获取表名+TableName
        /// <summary> 
        /// 获取表名 
        /// </summary> 
        /// <param name="prev">数据库表名前缀</param> 
        /// <returns></returns> 
        public static string TableName(string prev = "")
        {
            Type t = typeof(TModel);
            TableInfoAttribute tableInfo = t.GetCustomAttribute(typeof(TableInfoAttribute), true) as TableInfoAttribute;
            return tableInfo != null ? tableInfo.TableName : string.Concat(prev, t.Name);
        }
        #endregion

        #region Select 查询语句+GetQuerySql
        /// <summary> 
        /// Select 查询语句 
        /// </summary> 
        /// <returns></returns> 
        public static string GetQuerySql()
        {
            StringBuilder sql = new StringBuilder("select * from ");
            sql.Append(TableName());

            return sql.ToString();
        }
        #endregion

        #region Insert非Null属性的对象实例 Sql 语句+GetInsertSql
        /// <summary> 
        /// Insert 非Null属性的对象实例 Sql 语句 
        /// </summary> 
        /// <param name="model"></param> 
        /// <returns></returns> 
        public static string GetInsertSql(TModel model)
        {
            StringBuilder sql = new StringBuilder("insert into ");

            string[] props = Propertys(model);
            sql.Append(TableName());
            sql.Append("(");
            sql.Append(string.Join(",", props));
            sql.Append(") values(@");
            sql.Append(string.Join(",@", props));
            sql.Append(");select @@IDENTITY");

            return sql.ToString();
        }
        #endregion

        #region Delete Sql 语句+GetDeleteSql
        /// <summary> 
        /// Delete Sql 语句 
        /// </summary> 
        /// <returns></returns> 
        public static string GetDeleteSql()
        {
            return string.Format(@"delete from {0} where {1} in @IdList", TableName(), PrimaryKey);
        }

        /// <summary> 
        /// Delete Sql 语句 
        /// </summary> 
        /// <returns></returns> 
        public static string GetDeleteAllSql()
        {
            return string.Format(@"delete from {0} ", TableName());
        }

        #endregion

        #region Update 非Null属性的对象实例 Sql语句+GetUpdateSql
        /// <summary> 
        /// Update 非Null属性的对象实例 Sql语句 
        /// </summary> 
        /// <param name="model"></param> 
        /// <returns></returns> 
        public static string GetUpdateSql(TModel model)
        {
            StringBuilder sql = new StringBuilder("update ");
            string[] props = Propertys(model);
            sql.Append(TableName());
            sql.Append(" set ");
            foreach (string propName in props)
            {
                sql.Append(propName + "=@" + propName + ",");
            }
            sql.Remove(sql.Length - 1, 1);
            sql.Append(" where " + PrimaryKey + "=@Id");
            return sql.ToString();
        }
        #endregion

        #region 非主键且非Null属性集合+Propertys
        /// <summary> 
        /// 非主键且非Null属性 
        /// </summary> 
        /// <param name="model"></param> 
        /// <returns></returns> 
        public static string[] Propertys(TModel model)
        {
            PropertyInfo[] props = typeof(TModel).GetProperties();
            List<string> list = new List<string>();
            string key = PrimaryKey;
            string columnName = string.Empty;

            if (props != null && props.Length > 0)
            {
                foreach (PropertyInfo prop in props)
                {
                    columnName = GetAttributeName(prop);

                    if (prop.GetValue(model, null) != null && !columnName.Equals(key, StringComparison.OrdinalIgnoreCase))
                    {
                        list.Add(columnName);
                    }
                }
            }

            return list.ToArray();
        }

        private static string GetAttributeName(PropertyInfo p)
        {
            ColumnAttribute columnInfo = p.GetCustomAttribute(typeof(ColumnAttribute), true) as ColumnAttribute;
            return columnInfo != null ? columnInfo.ColumnName : p.Name;
        }
        #endregion
    }
}
